package com.inspur.dgov.policy.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.inspur.dgov.common.tool.api.R;
import com.inspur.dgov.common.tool.constant.AppConstant;
import com.inspur.dgov.common.tool.page.SelectPage;
import com.inspur.dgov.policy.entity.FilePolicy;
import com.inspur.dgov.policy.entity.InfoPolicy;
import com.inspur.dgov.policy.entity.PolicySubjectRelation;
import com.inspur.dgov.policy.service.EsPolicyService;
import com.inspur.dgov.policy.service.FilePolicyService;
import com.inspur.dgov.policy.service.InfoPolicyService;
import com.inspur.dgov.policy.service.PolicySubjectRelationService;
import com.inspur.dgov.policy.vo.InfoPolicyVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 政策信息表 控制器
 *
 * @Author chengxin.ju
 * @Date 20/3/18
 * @Version 1.0
 * @Description 政策信息表 控制器
 */
@RestController
@RequestMapping("/info")
@Api(value = "政策信息", tags = "政策信息")
@Slf4j
public class InfoPolicyController {

    @Autowired
    private InfoPolicyService infoPolicyService;

    @Autowired
    private FilePolicyService filePolicyService;

    @Autowired
    private PolicySubjectRelationService policySubjectRelationService;

    @Autowired
    private EsPolicyService esPolicyService;

    @Value("${es.push.flag}")
    private boolean esPushFlag;

    /**
     * 政策信息列表
     */
    @PostMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "basicTitle", value = "标题", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "startDate", value = "发文日期（起）", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "endDate", value = "发文日期（止）", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "basicStatus", value = "审核状态", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "basicState", value = "发文状态", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "regionCode", value = "区划简码", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "regionLevel", value = "区划范围", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "extendKeywords", value = "关键词", paramType = "query", dataType = "string")
    })
    @ApiOperation(value = "政策信息列表", notes = "传入标题、发文日期范围或状态", position = 1)
    public R<IPage<InfoPolicy>> page(@ApiIgnore @RequestParam Map<String, Object> query, Page page) {
        //判断查询条件中区划范围
        Object region = query.get("regionCode");
        if (null != region) {
            String regionCode = region.toString();
            String level = query.get("regionLevel") + "";
            if (AppConstant.DB_STATUS_NORMAL.equals(level)) {
                regionCode = regionCode.replaceAll("0+$", "");
                int len = regionCode.length();
                //截取后的区划编码长度为奇数时需末尾添加0
                if ((len & 1) == 1) {
                    regionCode = regionCode + "0";
                }
                query.put("regionCode", regionCode);
            }
        }
        //TODO 根据当前用户所属租户过滤数据

        IPage<InfoPolicy> pages = this.infoPolicyService.selectPolicyPage(page, query);
        return R.data(pages);
    }

    /**
     * 撤回政策
     */
    @PostMapping("/back")
    @ApiOperation(value = "撤回政策", notes = "传入政策ID", position = 2)
    public R back(@RequestBody InfoPolicy policy) {
        if (esPushFlag) {
            //从ES删除该政策
            this.esPolicyService.deleteEsPolicy(policy.getId());
        }
        //更新发布状态
        InfoPolicy param = new InfoPolicy();
        param.setId(policy.getId());
        param.setBasicState(AppConstant.DB_STATUS_ABNORMAL);
        boolean ret = this.infoPolicyService.updateById(param);
        return R.status(ret);
    }

    /**
     * 删除政策
     */
    @PostMapping("/remove")
    @ApiOperation(value = "删除政策", notes = "传入政策ID", position = 3)
    public R remove(@RequestBody InfoPolicy policy) {
        //判断是否是已撤回状态
        InfoPolicy record = this.infoPolicyService.getById(policy.getId());
        if (!AppConstant.DB_STATUS_ABNORMAL.equals(record.getBasicState())) {
            return R.fail("该政策已经发布，不能删除");
        }
        //物理删除
        boolean ret = this.infoPolicyService.removeById(policy.getId());
        return R.status(ret);
    }

    /**
     * 政策信息详情
     */
    @PostMapping("/detail")
    @ApiOperation(value = "政策信息详情", notes = "政策信息详情数据", position = 4)
    public R<InfoPolicyVO> detail(@RequestBody InfoPolicy policy) {
        InfoPolicyVO infoPolicyVo = new InfoPolicyVO();

        //获取政策详情
        InfoPolicy detail = this.infoPolicyService.getById(policy.getId());
        BeanUtil.copyProperties(detail, infoPolicyVo);

        //获取政策文件内容
        if (StrUtil.isNotBlank(detail.getBasicContentId())) {
            FilePolicy filePolicy = this.filePolicyService.getById(detail.getBasicContentId());
            if (null != filePolicy) {
                if (StrUtil.isBlank(filePolicy.getContentHtml())) {
                    infoPolicyVo.setContentHtml(filePolicy.getContent());
                } else {
                    infoPolicyVo.setContentHtml(filePolicy.getContentHtml());
                }
            }
        }
        //获取政策专题关联
        List<PolicySubjectRelation> subjectList = this.policySubjectRelationService.getPolicySubjectRelationList(detail.getId());
        if (null != subjectList && subjectList.size() > 0) {
            List<String> subjectIds = subjectList.stream().map(PolicySubjectRelation::getSubjectId)
                    .collect(Collectors.toList());
            infoPolicyVo.setSubjectList(StrUtil.join(",", subjectIds));
        }
        //获取父政策
        String parentId = detail.getParentId();
        if (StrUtil.isNotBlank(parentId)) {
            List<String> list = StrUtil.split(parentId,',');
            List<InfoPolicy> parentList = this.infoPolicyService.list(new QueryWrapper<InfoPolicy>().lambda().in(InfoPolicy::getId, list));
            if (null != parentList && parentList.size() > 0) {
                List<String> parentNames = parentList.stream().map(InfoPolicy::getBasicTitle)
                        .collect(Collectors.toList());
                infoPolicyVo.setParentName(StrUtil.join(",", parentNames));
            }
        }
        return R.data(infoPolicyVo);
    }

    /**
     * 政策信息更新保存
     *
     * @param policy
     * @return
     */
    @PostMapping("/save")
    @ApiOperation(value = "政策信息更新保存", notes = "传入政策信息", position = 5)
    public R save(@RequestBody JSONObject policy) {
        InfoPolicy detail = this.buildPolicy(policy);

        //更新政策内容表
        FilePolicy file = new FilePolicy();
        file.setId(detail.getBasicContentId());
        file.setContentHtml(policy.getString("contentHtml"));
        if (null !=  this.filePolicyService.getById(file.getId())) {
            this.filePolicyService.updateById(file);
        } else {
            this.filePolicyService.save(file);
        }

        //更新政策专题关系表
        Object subjectList = policy.get("subjectList");
        if (null != subjectList) {
            List<String> subjectExtend = (ArrayList<String>)subjectList;
            if (subjectExtend.size() > 0) {
                UpdateWrapper<PolicySubjectRelation> updateWrapper = new UpdateWrapper();
                updateWrapper.lambda().eq(PolicySubjectRelation::getPolicyId, detail.getId());
                this.policySubjectRelationService.remove(updateWrapper);
                for (String subjectId : subjectExtend) {
                    PolicySubjectRelation relation = new PolicySubjectRelation();
                    relation.setPolicyId(detail.getId());
                    relation.setSubjectId(subjectId);
                    this.policySubjectRelationService.save(relation);
                }
            }
        }

        boolean ret = this.infoPolicyService.updateById(detail);
        return R.status(ret);
    }

    /**
     * 政策信息审核发布
     *
     * @param policy
     * @return
     */
    @PostMapping("/confirm")
    @ApiOperation(value = "政策信息审核发布", notes = "传入政策信息", position = 6)
    public R confirm(@RequestBody JSONObject policy) {
        InfoPolicy detail = this.buildPolicy(policy);

        //更新政策内容表
        FilePolicy file = new FilePolicy();
        file.setId(detail.getBasicContentId());
        file.setContentHtml(policy.getString("contentHtml"));
        if (null !=  this.filePolicyService.getById(file.getId())) {
            this.filePolicyService.updateById(file);
        } else {
            this.filePolicyService.save(file);
        }

        //更新政策专题关系表
        Object subjectList = policy.get("subjectList");
        if (null != subjectList) {
            List<String> subjectExtend = (ArrayList<String>)subjectList;
            if (subjectExtend.size() > 0) {
                UpdateWrapper<PolicySubjectRelation> updateWrapper = new UpdateWrapper();
                updateWrapper.lambda().eq(PolicySubjectRelation::getPolicyId, detail.getId());
                this.policySubjectRelationService.remove(updateWrapper);
                for (String subjectId : subjectExtend) {
                    PolicySubjectRelation relation = new PolicySubjectRelation();
                    relation.setPolicyId(detail.getId());
                    relation.setSubjectId(subjectId);
                    this.policySubjectRelationService.save(relation);
                }
            }
        }

        String state = detail.getBasicState();
        detail.setBasicState(AppConstant.DB_STATUS_NORMAL);
        boolean ret = this.infoPolicyService.updateById(detail);

        if (esPushFlag) {
            if (AppConstant.DB_STATUS_NORMAL.equals(state)) {
                //更新ES政策数据
                this.esPolicyService.updateEsPolicy(detail.getId());
            } else {
                //插入ES政策数据
                this.esPolicyService.insertEsPolicy(detail.getId());
            }
        }
        return R.status(ret);
    }

    /**
     * 获取父级政策
     *
     * @param query
     */
    @PostMapping("/parent")
    @ApiOperation(value = "政策信息审核发布", notes = "传入政策信息", position = 6)
    public R<SelectPage<InfoPolicy>> parent(@ApiIgnore @RequestParam Map<String, Object> query, Page page) {
        IPage<InfoPolicy> pages = this.infoPolicyService.selectParentPolicyPage(page, query);
        SelectPage parentPage = new SelectPage();
        parentPage.setList(pages.getRecords());
        parentPage.setTotalRow(pages.getTotal());
        parentPage.setPageNumber(pages.getCurrent());
        parentPage.setTotalPage(pages.getPages());
        parentPage.setPageSize(pages.getSize());
        return R.data(parentPage);
    }

    /**
     * 政策信息新增保存
     *
     * @param policy
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "政策信息新增保存", notes = "传入政策信息", position = 7)
    public R add(@RequestBody JSONObject policy) {
        InfoPolicy detail = this.buildPolicy(policy);
        String id = detail.getId();
        boolean ret = false;
        //新增
        if (StrUtil.isBlank(id)) {
            id = IdUtil.simpleUUID();
            detail.setId(id);
            detail.setBasicContentId(id);
            ret = this.infoPolicyService.save(detail);
            FilePolicy file = new FilePolicy();
            file.setId(detail.getBasicContentId());
            String contentHtml = policy.getString("contentHtml");
            String content = StrUtil.removeAll(HtmlUtil.cleanHtmlTag(contentHtml), '\t', '\r', '\n', ' ');
            file.setContentHtml(contentHtml);
            file.setContent(content);
            this.filePolicyService.save(file);
        } else {
            //变更
            ret = this.infoPolicyService.updateById(detail);
            //更新政策内容表
            FilePolicy file = new FilePolicy();
            file.setId(detail.getBasicContentId());
            String contentHtml = policy.getString("contentHtml");
            String content = StrUtil.removeAll(HtmlUtil.cleanHtmlTag(contentHtml), '\t', '\r', '\n', ' ');
            file.setContentHtml(contentHtml);
            file.setContent(content);
            this.filePolicyService.updateById(file);
        }

        //更新政策专题关系表
        Object subjectList = policy.get("subjectList");
        if (null != subjectList) {
            List<String> subjectExtend = (ArrayList<String>)subjectList;
            if (subjectExtend.size() > 0) {
                UpdateWrapper<PolicySubjectRelation> updateWrapper = new UpdateWrapper();
                updateWrapper.lambda().eq(PolicySubjectRelation::getPolicyId, detail.getId());
                this.policySubjectRelationService.remove(updateWrapper);
                for (String subjectId : subjectExtend) {
                    PolicySubjectRelation relation = new PolicySubjectRelation();
                    relation.setPolicyId(detail.getId());
                    relation.setSubjectId(subjectId);
                    this.policySubjectRelationService.save(relation);
                }
            }
        }

        return R.status(ret);
    }

    /**
     * 录入政策撤回
     */
    @PostMapping("/addBack")
    @ApiOperation(value = "录入政策撤回", notes = "传入政策ID", position = 8)
    public R addBack(@RequestBody InfoPolicy policy) {
        //更新发布状态
        InfoPolicy param = new InfoPolicy();
        param.setId(policy.getId());
        param.setBasicStatus(AppConstant.DB_STATUS_ABNORMAL);
        boolean ret = this.infoPolicyService.updateById(param);
        return R.status(ret);
    }

    /**
     * 从前台JSON对象构建政策对象
     * @param policy
     * @return
     */
    private InfoPolicy buildPolicy(JSONObject policy) {
        InfoPolicy detail = new InfoPolicy();
        String id = policy.getString("id");
        detail.setId(id);
        detail.setBasicTitle(policy.getString("basicTitle"));
        detail.setBasicIssuedNumber(policy.getString("basicIssuedNumber"));
        detail.setRegionName(policy.getString("regionName"));
        detail.setRegionCode(policy.getString("regionCode"));
        detail.setOrgName(policy.getString("orgName"));
        detail.setOrgCode(policy.getString("orgCode"));
        detail.setBasicDepartmentName(policy.getString("basicDepartmentName"));
        detail.setBasicSourceUrl(policy.getString("basicSourceUrl"));
        detail.setBasicReleaseDate(policy.getString("basicReleaseDate"));
        detail.setBasicSubjectWords(policy.getString("basicSubjectWords"));
        Object basicSubjectClassification = policy.get("basicSubjectClassification");
        if (null != basicSubjectClassification) {
            List<String> classificationList = (ArrayList<String>)basicSubjectClassification;
            if (classificationList.size() > 0) {
                detail.setBasicSubjectClassification(StrUtil.join(",", classificationList));
            }
        }
        String basicContentId = policy.getString("basicContentId");
        detail.setBasicContentId(basicContentId);
        detail.setBasicAttachementUrl(policy.getString("basicAttachementUrl"));
        detail.setCollectStyle(policy.getString("collectStyle"));
        detail.setCollecterId(policy.getString("collecterId"));
        detail.setCollecterName(policy.getString("collecterName"));
        detail.setCollectTenant(policy.getString("collectTenant"));
        detail.setCollectDate(policy.getString("collectDate"));
        String basicState = policy.getString("basicState");
        if (StrUtil.isBlank(basicState))
            basicState = AppConstant.DB_STATUS_ABNORMAL;
        detail.setBasicState(basicState);
        String basicStatus = policy.getString("basicStatus");
        if (StrUtil.isBlank(basicStatus))
            basicStatus = AppConstant.DB_STATUS_ABNORMAL;
        detail.setBasicStatus(basicStatus);
        detail.setExtendSubjectUpdate(policy.getString("extendSubjectUpdate"));
        detail.setExtendDocType(policy.getString("extendDocType"));
        detail.setExtendKeywords(policy.getString("extendKeywords"));
        detail.setExtendUseDate(LocalDate.now());
        detail.setExtendSummary(policy.getString("extendSummary"));
        Object extendCorporation = policy.get("extendCorporation");
        if (null != extendCorporation) {
            List<String> corporationList = (ArrayList<String>)extendCorporation;
            if (corporationList.size() > 0) {
                detail.setExtendCorporation(StrUtil.join(",", corporationList));
            }
        }
        detail.setExtendRedundantField1(policy.getString("extendRedundantField1"));
        detail.setExtendRedundantField2(policy.getString("extendRedundantField2"));
        detail.setExtendRedundantField3(policy.getString("extendRedundantField3"));
        detail.setExtendRedundantField4(policy.getString("extendRedundantField4"));
        detail.setExtendRedundantField5(policy.getString("extendRedundantField5"));
        detail.setModifyTime(LocalDateTime.now());
        //上级政策
        String parentId = policy.getString("parentId");
        detail.setParentId(parentId);
        return detail;
    }

}
